## Sid Meier's Civilization 4
## Copyright Firaxis Games 2005
## 
## Author : TheLopez - Great Doctor Utilities
## Date : 01.22.2006
## version : 0.3
## 

from CvPythonExtensions import *
import CvUtil
import PyHelpers
import CvConfigParser

PyPlayer = PyHelpers.PyPlayer
PyGame = PyHelpers.PyGame()
PyInfo = PyHelpers.PyInfo
BuildingInfo = PyInfo.BuildingInfo
gc = CyGlobalContext()	

MAXRANCEIL = 100

# Increase or decrease the value to change chance that a great doctor will 
# teach one or more units one of his skills. The default value represents 
# a 4% chance that the great doctor will teach his craft
# Default value is 0.04
g_iGreatDoctorTeachChance = int(0.04 * MAXRANCEIL)

# Change this to false if all the units on the same plot as the great 
# doctor should have a chance of being taught.
# Default value is true
g_bTeachRandomUnit = true

# Change this to false to suppress the great doctor teaching messages.
# Default value is false
g_bSuppressGreatDoctorMessages = false


######################################################
###   Utility class used for great doctor          ###
###   operations                                   ###
######################################################

class GreatDoctorUtils:

	def __init__(self):
		self.firsttime = true

		global g_iGreatDoctorTeachChance
		global g_bTeachRandomUnit
		global g_bSuppressGreatDoctorMessages
		
		config = CvConfigParser.CvConfigParser("ViSa_v3.ini")

		if(config != None):
			g_bTeachRandomUnit = config.getboolean("Great Doctor", "Teach Random Unit", True)

			g_iGreatDoctorTeachChance = int(config.getfloat("Great Doctor", "Great Doctor Teach Chance", 0.04)*100)

			g_bSuppressGreatDoctorMessages = config.getboolean("Great Doctor", "Suppress Great Doctor Messages", false)


	# Goes through the list of great doctors the player owns. If one or more units
	# are in the same plot as the great doctor, the great doctor will attempt to 
	# teach one or more of their promotions to the unit.
	def doAttemptTeachCraft(self, iPlayer):

		# Get the player object
		player = PyPlayer(iPlayer)

		# Return immediately if player contains an invalid value.
		if(player == None):
			return
			
		iGreatDoctor = gc.getInfoTypeForString("UNIT_DOCTOR")

		# Get the list of great doctors the player owns
		greatDoctorList = player.getUnitsOfType(iGreatDoctor)

		# Go through each one of the player's doctors
		for doctor in greatDoctorList :

			# Get the plot the doctor is in
			plot = doctor.plot()

			# Get the units that are currently at the plot
			unitList = self.getPlotUnitList(plot)
			
			# If the mod is configured to teach one unit randomly then teach
			# a unit randomly and continue to the next great doctor.
			if(g_bTeachRandomUnit):
				randNum = gc.getGame().getMapRand().get(MAXRANCEIL,"Great Doctor") 

				# If the unit beat the odds then have the doctor teach the unit
				# one of their skills
				if(g_iGreatDoctorTeachChance > randNum):
					self.giveDoctorPromotion(doctor,unitList[gc.getGame().getMapRand().get(len(unitList),"Great Doctor")])
					continue
			
			# Go through each of the units in the list and try to have the
			# great doctor teach them a skill
			for unit in unitList:

				randNum = gc.getGame().getMapRand().get(MAXRANCEIL,"Great Doctor") 
				
				# If the unit beat the odds then have the doctor teach the unit
				# one of their skills
				if(g_iGreatDoctorTeachChance > randNum):
					self.giveDoctorPromotion(doctor,unit)


	# Assigns the next doctor promotion from a doctor to the unit passed in.
	def giveDoctorPromotion(self,doctor,unit):
		iMedic1 = gc.getInfoTypeForString("PROMOTION_MEDIC1")
		iMedic2 = gc.getInfoTypeForString("PROMOTION_MEDIC2")
		iMedic3 = gc.getInfoTypeForString("PROMOTION_MEDIC3")
		iHeal1 = gc.getInfoTypeForString("PROMOTION_HEAL1")
		iHeal2 = gc.getInfoTypeForString("PROMOTION_HEAL2")
		iHeal3 = gc.getInfoTypeForString("PROMOTION_HEAL3")
		iMarch = gc.getInfoTypeForString("PROMOTION_MARCH")

		# Build the doctor promotion array
		doctorPromotionList = [iMedic1,iMarch,iMedic2,iMedic3,iHeal1,iHeal2,iHeal3]
		
		# Go through all of the doctor promotions 
		for i in range(len(doctorPromotionList)):

			# If the unit doesn't have the next promotion then have the doctor
			# teach that promotion to the unit.
			if(not unit.isHasPromotion(doctorPromotionList[i])):
				# Debug message
				# CyInterface().addImmediateMessage(unit.getName() + " was taught " + gc.getPromotionInfo(doctorPromotionList[i]).getDescription(),"")

				# Display the message informing the player that their unit has been
				# taught one of the doctor's skills
				if(not g_bSuppressGreatDoctorMessages):
					unitName = unit.getName()

					# Get the actual name of the unit if they have been given some
					# name that isn't the unit type name
					if(unit.getNameNoDesc()):
						unitName = unit.getNameNoDesc()

					promoMessage = unitName + " was taught " + gc.getPromotionInfo(doctorPromotionList[i]).getDescription() +" by "+ doctor.getNameNoDesc()

					# Display the actual message to the player
					CyInterface().addMessage(unit.getOwner(), false, 20, promoMessage, "", 0, gc.getPromotionInfo(doctorPromotionList[i]).getButton(), ColorTypes(0), unit.getX(), unit.getY(), True, True) 
				
				# Give the unit the promotion	
				unit.setHasPromotion(doctorPromotionList[i], true)

				return


	# Returns the list of units on a particular plot
	def getPlotUnitList(self,objPlot):
		' unitList - All of the units in the objPlot'
		unitList = []

		# Return immediately if the objPlot is not valid
		if(objPlot == None):
			return []
			
		unitCount = objPlot.getNumUnits()

		# Go through all of the units in a plot
		for i in range(unitCount):

			# Get the unit from the plot
			unit = objPlot.getUnit(i)
			
			# If the unit isn't dead then add them to the list
			if(not unit.isDead()):
				unitList.append(unit)
		
		return unitList
